package com.spring.design.singleton;

/**
 * 单例模式
 * JDK案例：Runtime
 */
public class SingletonTest {
    public static void main(String[] args) {
        Singleton2 instance = Singleton2.getInstance();
        Singleton2 instance2 = Singleton2.getInstance();
        System.out.println(instance == instance2);
        System.out.println("ins1:"+ instance.hashCode());
        System.out.println("ins2:"+ instance2.hashCode());

        Sing sin = Sing.INSTANCE;
        Sing sin2 = Sing.INSTANCE;
        System.out.println("sin:"+ sin.hashCode());
        System.out.println("sin2:"+ sin2.hashCode());
    }
}

//推荐0：饿汉式，可防止线程安全，但会增加内存开销
class Singlet{
    private static final Singlet singlet=new Singlet();
    private Singlet(){}
    public static Singlet getInstance(){
        return singlet;
    }
}

//单例模式推荐用法1：双重检查-解决线程安全问题，同时解决懒加载和效率问题
class Singleton {

    private static volatile Singleton singleton;

    private Singleton(){}

    public static Singleton getInstance(){
        if (singleton == null){
            synchronized (Singleton.class){
                if (singleton == null){
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

//推荐2：静态内部类
class Singleton2 {

    private Singleton2(){}

    //JVM在装载类时线程是安全的，JVM保证了安全，加载时并不会实例化
    private static class SingletonIns2{
        private static final Singleton2 INSTANCE = new Singleton2();
    }

    //调用此方法才实例化的，延迟加载。
    public static synchronized Singleton2 getInstance(){

        return SingletonIns2.INSTANCE;
    }
}

//推荐3：枚举
enum Sing{
    INSTANCE;
    public void method(){
        System.out.println("OK");
    }

}
